#include "type.h"
#include "const.h"
#include "protectmode.h"
#include "process.h"
#include "prototype.h"
#include "string.h"




extern int32	disp_pos;
extern int8		gdt_ptr[6];
extern DESCRIPTOR gdt[GDT_SIZE];
extern int8		idt_ptr[6];
extern GATE		idt[IDT_SIZE];
extern char		ks1[STACK_SIZE_TOTAL];
extern char		us1[STACK_SIZE_TOTAL];
extern char		ks2[STACK_SIZE_TOTAL];
extern char		us2[STACK_SIZE_TOTAL];
extern char		ks3[STACK_SIZE_TOTAL];
extern char		us3[STACK_SIZE_TOTAL];
extern void testp2();
extern void p2();
extern void p3();
PROCESS proc_table[NR_TASKS];
PROCESS	current_proc;
int32	current_proc_id = 0;



/*======================================================================*
                               kill_curr_proc
 *======================================================================*/
PUBLIC void kill_curr_proc(){
	proc_table[current_proc_id].running_state=1;
	schedule();
}



//进程调度函数
PUBLIC void schedule()
{
	
	int32 SelectTss;
	int16 TSStemp;
	/*
	if(current_proc_id == 0)
	{
		current_proc_id = 1;
		TSStemp = proc_table[1].TssSelector;
	}
	else
	{
		current_proc_id = 0;
		TSStemp = proc_table[0].TssSelector;
	}*/
	
	current_proc_id = (current_proc_id + 1) % NR_TASKS;	//选择一个进程
	while(proc_table[current_proc_id].running_state!=0){
		current_proc_id = (current_proc_id + 1) % NR_TASKS;
	}
	TSStemp = proc_table[current_proc_id].TssSelector;	//取得进程的TSS的选择子
	SelectTss = (int32)TSStemp;				
	switchto(SelectTss);					//切换到进程
}
//初始化进程，这里初始化了3个进程，分别p1,p2,p3
PUBLIC void initProcess()
{


	int i = 0;
	int t_index_tss = INDEX_TSS,t_index_ldt = INDEX_LDT_FIRST;
	
	init_descriptor((&gdt[INDEX_TSS]),vir2phys(seg2phys(SELECTOR_KERNEL_DS),(int32)(&(proc_table[0].tss))),sizeof(proc_table[0].tss)-1,DA_386TSS);
	init_descriptor(&gdt[INDEX_LDT_FIRST],vir2phys(seg2phys(SELECTOR_KERNEL_DS), proc_table[0].ldts),LDT_SIZE * sizeof(DESCRIPTOR)- 1,DA_LDT);
	
	/* init LDT */
	
	memcpy(&proc_table[0].ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(DESCRIPTOR));
	proc_table[0].ldts[0].attr1 = DA_C | PRIVILEGE_USER << 5;	// change the DPL
	memcpy(&proc_table[0].ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(DESCRIPTOR));
	proc_table[0].ldts[1].attr1 = DA_DRW | PRIVILEGE_USER << 5;	// change the DPL
	
	/*init TSS */
	/*memset(&p_proc.tss, 0, sizeof(p_proc.tss));*/
	proc_table[0].tss.backlink = 0;
	proc_table[0].tss.esp0 = (int32)ks1 + STACK_SIZE_TOTAL;
	proc_table[0].tss.ss0 = 0x10;	
	proc_table[0].tss.esp1 = 0;
	proc_table[0].tss.ss1 = 0;
	proc_table[0].tss.esp2 = 0;
	proc_table[0].tss.ss2 = 0;
	proc_table[0].tss.cr3 = 0;
	proc_table[0].tss.eip = 0;
	proc_table[0].tss.flags = 0;
	proc_table[0].tss.eax = 0;
	proc_table[0].tss.ecx = 0;
	proc_table[0].tss.edx = 0;
	proc_table[0].tss.ebx = 0;
	proc_table[0].tss.esp = (int32)us1 + STACK_SIZE_TOTAL;
	proc_table[0].tss.ebp = 0;
	proc_table[0].tss.esi = 0;
	proc_table[0].tss.edi = 0;
	proc_table[0].tss.es = 0;
	proc_table[0].tss.cs = 0;
	proc_table[0].tss.ss = 0x0f;
	proc_table[0].tss.ds = 0;
	proc_table[0].tss.fs = 0;
	proc_table[0].tss.gs = 0;
	proc_table[0].tss.ldt = INDEX_LDT_FIRST * 8;
	proc_table[0].tss.trap = 0x8000000;
	
	proc_table[0].TssSelector = INDEX_TSS * 8;
	
	proc_table[0].running_state=0;
	//proc_table[0].tss.iobase = sizeof(proc_table[0].tss);
	/*----------------------------------------------------task1----------------------------------------*/
	
	
	i++;
	t_index_tss += 2;
	t_index_ldt += 2;
	init_descriptor((&gdt[t_index_tss]),vir2phys(seg2phys(SELECTOR_KERNEL_DS),(int32)(&(proc_table[i].tss))),sizeof(proc_table[i].tss)-1,DA_386TSS);
	init_descriptor(&gdt[t_index_ldt],vir2phys(seg2phys(SELECTOR_KERNEL_DS), proc_table[i].ldts),LDT_SIZE * sizeof(DESCRIPTOR)- 1,DA_LDT);
	
	/* init LDT */
	
	memcpy(&proc_table[i].ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(DESCRIPTOR));
	proc_table[i].ldts[0].attr1 = DA_C | PRIVILEGE_USER << 5;	// change the DPL
	memcpy(&proc_table[i].ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(DESCRIPTOR));
	proc_table[i].ldts[1].attr1 = DA_DRW | PRIVILEGE_USER << 5;	// change the DPL
	
	/*init TSS */
	/*memset(&p_proc.tss, 0, sizeof(p_proc.tss));*/
	proc_table[i].tss.backlink = 0;
	proc_table[i].tss.esp0 = (int32)ks2 + STACK_SIZE_TOTAL;
	proc_table[i].tss.ss0 = 0x10;	
	proc_table[i].tss.esp1 = 0;
	proc_table[i].tss.ss1 = 0;
	proc_table[i].tss.esp2 = 0;
	proc_table[i].tss.ss2 = 0;
	proc_table[i].tss.cr3 = 0;
	proc_table[i].tss.eip = (int32)p2;
	proc_table[i].tss.flags = 0x200;
	proc_table[i].tss.eax = 0;
	proc_table[i].tss.ecx = 0;
	proc_table[i].tss.edx = 0;
	proc_table[i].tss.ebx = 0;
	proc_table[i].tss.esp = (int32)us2 + STACK_SIZE_TOTAL;
	proc_table[i].tss.ebp = 0;
	proc_table[i].tss.esi = 0;
	proc_table[i].tss.edi = 0;
	proc_table[i].tss.es = 0x0f;
	proc_table[i].tss.cs = 0x07;
	proc_table[i].tss.ss = 0x0f;
	proc_table[i].tss.ds = 0x0f;
	proc_table[i].tss.fs = 0x0f;
	proc_table[i].tss.gs = 0x1b;
	proc_table[i].tss.ldt = t_index_ldt * 8;
	proc_table[i].tss.trap = 0x8000000;
	
	proc_table[i].TssSelector = t_index_tss * 8;
	
	proc_table[i].running_state=0;
	

	i++;
	t_index_tss += 2;
	t_index_ldt += 2;
	init_descriptor((&gdt[t_index_tss]),vir2phys(seg2phys(SELECTOR_KERNEL_DS),(int32)(&(proc_table[i].tss))),sizeof(proc_table[i].tss)-1,DA_386TSS);
	init_descriptor(&gdt[t_index_ldt],vir2phys(seg2phys(SELECTOR_KERNEL_DS), proc_table[i].ldts),LDT_SIZE * sizeof(DESCRIPTOR)- 1,DA_LDT);
	
	/* init LDT */
	
	memcpy(&proc_table[i].ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3], sizeof(DESCRIPTOR));
	proc_table[i].ldts[0].attr1 = DA_C | PRIVILEGE_USER << 5;	// change the DPL
	memcpy(&proc_table[i].ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3], sizeof(DESCRIPTOR));
	proc_table[i].ldts[1].attr1 = DA_DRW | PRIVILEGE_USER << 5;	// change the DPL
	
	/*init TSS */
	/*memset(&p_proc.tss, 0, sizeof(p_proc.tss));*/
	proc_table[i].tss.backlink = 0;
	proc_table[i].tss.esp0 = (int32)ks3 + STACK_SIZE_TOTAL;
	proc_table[i].tss.ss0 = 0x10;	
	proc_table[i].tss.esp1 = 0;
	proc_table[i].tss.ss1 = 0;
	proc_table[i].tss.esp2 = 0;
	proc_table[i].tss.ss2 = 0;
	proc_table[i].tss.cr3 = 0;
	proc_table[i].tss.eip = (int32)p3;
	proc_table[i].tss.flags = 0x200;
	proc_table[i].tss.eax = 0;
	proc_table[i].tss.ecx = 0;
	proc_table[i].tss.edx = 0;
	proc_table[i].tss.ebx = 0;
	proc_table[i].tss.esp = (int32)us3 + STACK_SIZE_TOTAL;
	proc_table[i].tss.ebp = 0;
	proc_table[i].tss.esi = 0;
	proc_table[i].tss.edi = 0;
	proc_table[i].tss.es = 0x0f;
	proc_table[i].tss.cs = 0x07;
	proc_table[i].tss.ss = 0x0f;
	proc_table[i].tss.ds = 0x0f;
	proc_table[i].tss.fs = 0x0f;
	proc_table[i].tss.gs = 0x1b;
	proc_table[i].tss.ldt = t_index_ldt * 8;
	proc_table[i].tss.trap = 0x8000000;
	
	proc_table[i].TssSelector = t_index_tss * 8;
	
	proc_table[i].running_state=0;
	
}


